#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::yield
#include <vector>         // std::vector
#include <cmath>

#define N 100000000
#define N_THREAD 4

struct arg_t
{
    int rank;
    double local_sum;
};

void thread_fn(void *arg)
{
    struct arg_t *p_param = (struct arg_t *) arg;
    int i;
    p_param->local_sum = 0;
    for (i = p_param->rank; i < N; i += N_THREAD)
    {
	p_param->local_sum += std::sin(double(i));
    }
}

int main ()
{
    double sum = 0.0;
    std::vector<std::thread> threads;
    struct arg_t arg[N_THREAD];

    std::chrono::steady_clock::time_point t1
	= std::chrono::steady_clock::now(); 

    for (int i = 0; i < N_THREAD; i++)
    {
    	arg[i].rank = i;
	threads.push_back(std::thread(thread_fn, (void *)&arg[i]));
    }
    
    for (int i = 0; i < N_THREAD; i++)
    {
	threads[i].join();
	sum += arg[i].local_sum;
    }
    std::chrono::steady_clock::time_point t2
	= std::chrono::steady_clock::now(); 
    std::chrono::duration<double> time_span
	= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1);

    std::cout.precision(20);
    std::cout << "sum = " << sum << std::endl;
    std::cout << "It took me " << time_span.count() << " seconds." << std::endl;
    
    return 0;
}
